import hmac
import base64
import hashlib
import json
import time
import uuid
from urllib.parse import urlparse


def sha256(content):
    x = hashlib.sha256()
    x.update(content.encode())
    return x.hexdigest().upper()


def hmac_sha256(key, content):
    sign = hmac.new(key, content, digestmod="sha256").digest()
    ret = base64.b64encode(sign)
    return ret


def get_signature(url, ak, sk, app_key, body):
    # 创建待签名字符串

    # 一、header部分
    # 主要包括3个header需要作为签名内容：appkey、ctyun-eop-request-id、eop-date
    # 1. 首先通过uuid生成ctyun-eop-request-id
    request_id = str(uuid.uuid1())
    # 2. 获取当前时间戳并对时间进行格式化
    now_time = time.localtime()
    eop_date = time.strftime("%Y%m%dT%H%M%SZ", now_time)
    eop_date_simple = time.strftime("%Y%m%d", now_time)
    # 3. 对header部分按照字母顺序进行排序并格式化
    # camp_header = f"appkey:{app_key}\nctyun-eop-request-id:{request_id}\neop-date:{eop_date}\n"
    camp_header = f"ctyun-eop-request-id:{request_id}\neop-date:{eop_date}\n"

    # 二、query部分
    # 对url的query部分进行排序
    parsed_url = urlparse(url)
    query = parsed_url.query
    query_params = sorted(query.split("&"))
    after_query = ""
    for query_param in query_params:
        if len(after_query) < 1:
            after_query += query_param
        else:
            after_query += "&" + query_param

    # 三、body参数进行sha256摘要
    # sha256 body
    content_hash = sha256(json.dumps(body)).lower()
    # 完成创建待签名字符串
    pre_signature = camp_header + "\n" + after_query + "\n" + content_hash
    # 构造动态密钥
    k_time = hmac_sha256(sk.encode("utf-8"), eop_date.encode("utf-8"))
    k_ak = hmac_sha256(base64.b64decode(k_time), ak.encode("utf-8"))
    k_date = hmac_sha256(base64.b64decode(k_ak), eop_date_simple.encode("utf-8"))
    # 签名的使用
    signature = hmac_sha256(base64.b64decode(k_date), pre_signature.encode("utf-8"))
    # 将数据整合得到真正的header中的内容
    # sign_header = "{0} Headers=appkey;ctyun-eop-request-id;eop-date Signature={1}".format(ak, signature.decode())
    sign_header = "{0} Headers=ctyun-eop-request-id;eop-date Signature={1}".format(ak, signature.decode())
    # 返回request-id eop-date和sign_header
    return request_id, eop_date, sign_header

